package com.guo.anim.sunset;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;

import com.guo.anim.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 本次加载中动效分为4个步骤实现：1.太阳落下{@link #sunSet()}；2.月亮升起并且星星显示{@link #moonRise()}；
 * 3.月亮和星星收起{@link #moonStarVanish()}；4.太阳升起{@link #sunRise()}
 */
public class LoadingView extends FrameLayout {
    private SunMoonView sunMoonView;
    /**
     * 全部的星星将通过addView添加，此处缓存添加的星星对象，用于对星星设置动效
     */
    private List<StarView> starViews = new ArrayList<>();
    /**
     * 整体布局宽度，高度
     */
    private int width , height;
    /**
     * 太阳的视图半径，星星最大半径
     */
    private int sunRadius , starMaxRadius;
    /**
     * 太阳和月亮落下，升起时的位移距离
     */
    private int shiftDistance;
    /**
     * 上升和下降的组合动效
     */
    private AnimatorSet upAnimatorSet,downAnimatorSet;
    private static final String TAG = "LoadingView";

    public LoadingView(Context context) {
        super(context);

    }

    public LoadingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public LoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context , AttributeSet attrs){
        LayoutInflater.from(context).inflate(R.layout.layout_loading_view,this , true);
        sunMoonView = findViewById(R.id.sun_moon_view);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        height = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
        sunRadius = Math.min(width , height) / 5;
        starMaxRadius = sunRadius / 2;
        shiftDistance = height/2 + sunRadius;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        removeAllViews();
        post(new Runnable() {
            @Override
            public void run() {
                layoutSunMoon();
                sunSet();
            }
        });
    }

    /**
     * 设置太阳月亮初始位置
     */
    private void layoutSunMoon(){
        ViewGroup.MarginLayoutParams layoutParams  = (ViewGroup.MarginLayoutParams)sunMoonView.getLayoutParams();
        layoutParams.width = 2*sunRadius;
        layoutParams.height = layoutParams.width;
        layoutParams.leftMargin = width/2 - sunRadius;
        layoutParams.topMargin = height/2 - sunRadius;
        sunMoonView.setLayoutParams(layoutParams);
        addView(sunMoonView);
    }

    /**
     * 随机设置星星的位置
     */
    private void layoutStar(){
        Random random = new Random();
        int maxNum = height*2/5/2/starMaxRadius * width/2/starMaxRadius;
        int setNum = maxNum /2;
        //可以布置的行数
        int rows = height*2/5/2/starMaxRadius;
        //可以布置的列数
        int lines = width/2/starMaxRadius;
        starViews.clear();
        Log.d(TAG,"starMaxRadius = "+starMaxRadius+",sunRadius = "+sunRadius+",rows = "+rows + ",setNum = "+setNum);
        if(setNum > 0 ){
            for(int i = 0 ; i < setNum ; i++){
                StarView starView = new StarView(getContext());
                int x = i%lines*2*starMaxRadius + random.nextInt(starMaxRadius);
                int y = i/lines*2*starMaxRadius + random.nextInt(starMaxRadius);
                int size = starMaxRadius/2 + random.nextInt(starMaxRadius/2);
                starView.setPositionX(x);
                starView.setPositionY(y);
                starView.setSize(size);
                ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(size*2,size*2);
                layoutParams.leftMargin = x;
                layoutParams.topMargin = y;
                starView.setLayoutParams(layoutParams);
                addView(starView);
                starViews.add(starView);
            }
        }
    }

    /**
     * 将dp值转为像素
     * @param dp 输入dp类型尺寸
     * @return
     */
    private int dp2px(int dp){
        float dpi = getContext().getResources().getDisplayMetrics().density;
        return (int)(dp*dpi + 0.5f);
    }

    /**
     * 1.日落
     */
    private void sunSet(){
        ObjectAnimator bottomShiftAnimator = ObjectAnimator.ofFloat(sunMoonView,"translationY",
                0,shiftDistance);
        ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(sunMoonView , "rotation",0,360);
        downAnimatorSet = new AnimatorSet();
        downAnimatorSet.playTogether(bottomShiftAnimator , rotateAnimator);
        downAnimatorSet.setDuration(3000);
        downAnimatorSet.setInterpolator(new DecelerateInterpolator());
        downAnimatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        moonRise();
                    }
                } , 1000);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        downAnimatorSet.start();
    }


    /**
     * 2.月出：月亮升起，星星出现和闪烁
     */
    private void moonRise(){
        layoutStar();
        sunMoonView.changeShape();
        ObjectAnimator upShiftAnimator = ObjectAnimator.ofFloat(sunMoonView,"translationY",
                shiftDistance,0);
        ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(sunMoonView , "rotation",-20,20);
        rotateAnimator.setRepeatCount(2);
        rotateAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        upAnimatorSet = new AnimatorSet();
        upAnimatorSet.playTogether(upShiftAnimator , rotateAnimator);
        upAnimatorSet.setDuration(3000);
        upAnimatorSet.setInterpolator(new AccelerateInterpolator());
        upAnimatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        starShink();
                    }
                } , 1000);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        upAnimatorSet.start();
        starShow();
    }

    /**
     * 2.2设置星星闪烁
     */
    private void starShink(){
        for(int i = 0 ; i < starViews.size() ; i++){
            if(i % 2 == 0){
                ObjectAnimator alpha = ObjectAnimator.ofFloat(starViews.get(i),"alpha",
                        1.0f,0f);
                alpha.setDuration(1000);
                alpha.setRepeatCount(2);
                alpha.setRepeatMode(ValueAnimator.REVERSE);
                alpha.start();
                if((i == (starViews.size()-1)) | (i == (starViews.size()-1))){
                    alpha.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    moonStarVanish();
                                }
                            } , 1000);
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });
                }
            }
        }
    }

    /**
     * 2.1设置星星显示
     */
    private void starShow(){
        for(int i = 0 ; i < starViews.size() ; i++){
            ObjectAnimator bottomShiftAnimator = ObjectAnimator.ofFloat(starViews.get(i),"translationY",
                    -3*starViews.get(i).getSize(),starViews.get(i).getPositionY());
            bottomShiftAnimator.setDuration(3000);
            bottomShiftAnimator.start();
        }

    }

    /**
     * 3.1设置星星隐藏
     */
    private void starHide(){
        for(int i = 0 ; i < starViews.size() ; i++){
            ObjectAnimator upShiftAnimator = ObjectAnimator.ofFloat(starViews.get(i),"translationY",
                    starViews.get(i).getPositionY(),-3*starViews.get(i).getSize());
            upShiftAnimator.setDuration(3000);
            upShiftAnimator.start();
        }
    }

    /**
     * 3.月亮落下，星星收起
     */
    private void moonStarVanish(){
        ObjectAnimator bottomShiftAnimator = ObjectAnimator.ofFloat(sunMoonView,"translationY",
                0,shiftDistance);
        ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(sunMoonView , "rotation",-20,20);
        rotateAnimator.setRepeatCount(1);
        rotateAnimator.setRepeatMode(ObjectAnimator.REVERSE);
        downAnimatorSet = new AnimatorSet();
        downAnimatorSet.playTogether(bottomShiftAnimator , rotateAnimator);
        downAnimatorSet.setDuration(3000);
        downAnimatorSet.setInterpolator(new DecelerateInterpolator());
        downAnimatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        sunRise();
                    }
                } , 1000);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        downAnimatorSet.start();
        starHide();
    }

    /**
     * 4.太阳升起
     * 结束后重新执行onFinishInflated()方法
     */
    private void sunRise(){
        sunMoonView.changeShape();
        ObjectAnimator upShiftAnimator = ObjectAnimator.ofFloat(sunMoonView,"translationY",
                shiftDistance,0);
        upShiftAnimator.setDuration(3000);
        upShiftAnimator.setInterpolator(new AccelerateInterpolator());
        upShiftAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        //重写执行整个动效过程
                        onFinishInflate();
                    }
                } , 1000);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        upShiftAnimator.start();
    }
}
